/**
 * @
 * @FilePath     : app_builder.cpp
 * @Version      : 1.0
 * @Description  : 
 * @
 * @Author       : 岳凯(1585202329@qq.com)
 * @Date         : 2025-09-28 20:39:50
 * @
 * @LastEditors  : 岳凯(1585202329@qq.com)
 * @LastEditTime : 2025-09-29 20:43:10
 */
#include "app_builder.h"
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QCoreApplication>
#include <QGuiApplication>
#include <QQuickWindow>  // 添加这个头文件
#include <QResource>
#include <QFile>
// 编码设置相关头文件
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif

// Infrastructure
#include "infrastructure/di/servicecontainer.h"

// Presentation
#include "presentation/module_manager.h"

// 注册器
#include "bootstrap/infrastructure_registrar.h"
#include "bootstrap/application_registrar.h"

using namespace infrastructure;


namespace {

/**
 * @brief Qt应用程序初始化辅助类
 */
class QmlApplicationInitializer {
public:
    /**
     * @brief 配置QML应用程序属性
     */
    static void configureQmlApplication() {
#ifdef Q_OS_WINDOWS
        qputenv("QSG_RHI_BACKEND", "d3d11");
        qputenv("QT_QPA_DISABLE_REDIRECTION_SURFACE", "1");
#endif

        // 高DPI支持
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
        QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
            Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
        QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

        QQuickWindow::setDefaultAlphaBuffer(true);
    }

    /**
     * @brief 配置跨平台文本编码格式
     * @details 设置中文编码，确保正确显示中文，支持不同Qt版本
     */
    static void configureTextEncoding() {

#if (QT_VERSION <= QT_VERSION_CHECK(5, 0, 0))
#if _MSC_VER
        QTextCodec* codec = QTextCodec::codecForName("utf-8"); // 统一使用UTF-8
#else
        QTextCodec* codec = QTextCodec::codecForName("utf-8");
#endif
        QTextCodec::setCodecForLocale(codec);
        QTextCodec::setCodecForCStrings(codec);
        QTextCodec::setCodecForTr(codec);
#elif (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
        QTextCodec* codec = QTextCodec::codecForName("utf-8");
        QTextCodec::setCodecForLocale(codec);
#else
        // Qt6不需要额外设置
#endif

#if defined(_WIN32) || defined(_WIN64)
        // 最早设置控制台代码页为UTF-8，确保所有输出正常显示
        SetConsoleOutputCP(65001);
        SetConsoleCP(65001);
#endif

    }

    /**
     * @brief 设置应用程序元数据
     */
    static void setupApplicationMetadata(QGuiApplication* app) {
        app->setApplicationName("AGV_System");
        app->setApplicationVersion("1.0");
        app->setOrganizationName("AGV Technology Corp");

    }

    /**
     * @brief 初始化QML资源
     */
    static bool initializeQmlResources() {
        // Qt 6.8使用qt6_add_resources，资源通过前缀"/qml"注册
        return true;
    }

    /**
     * @brief 初始化资源系统
     * @param applicationDirPath 应用程序目录路径
     * @return true 如果资源加载成功
     */
    static bool initializeResources(const QString& applicationDirPath) {
        // Qt 6.8方式：
        // 1. QML资源通过qt6_add_resources自动嵌入到库中
        // 2. 其他外部资源文件（如果需要）可以动态加载

        QString rccPath = applicationDirPath + "/resources.rcc";
        if (QFile::exists(rccPath)) {
            if (QResource::registerResource(rccPath)) {
                return true;
            } else {
                qWarning() << "[QmlApplicationInitializer] Failed to register resource file:" << rccPath;
                // 对于QML应用，外部资源文件不是必需的，可以继续
            }
        } else {
        }

        return true; // QML资源已通过qt6_add_resources处理
    }
};

}

AppBuilder::AppBuilder()
    : QObject(nullptr)
    , m_container(std::make_shared<ServiceContainer>())
    , m_built(false)
{
}

AppBuilder::~AppBuilder()
{
    if (m_built) {
    }
    // 智能指针自动清理资源
}

bool AppBuilder::build()
{
    if (m_built) {
        return true;
    }

    try {
        // 首先配置文本编码（必须在所有其他操作之前）
        QmlApplicationInitializer::configureTextEncoding();

        // 第一阶段：配置Qt应用程序
        QmlApplicationInitializer::configureQmlApplication();

        // 初始化资源系统
        if (!QmlApplicationInitializer::initializeResources(QCoreApplication::applicationDirPath())) {
            qWarning() << "[AppBuilder] Resource initialization reported issues, but continuing...";
        }

        // 第二阶段：服务配置和初始化
        configureServices();

        initializeServices();

        // 第三阶段：创建并初始化presentation层
        if (!createPresentation()) {
            handleBuildError("表现层创建", "表现层创建失败");
            return false;
        }

        m_built = true;
        return true;

    } catch (const std::exception& ex) {
        handleBuildError("应用程序构建", QString::fromStdString(ex.what()));
        return false;
    } catch (...) {
        handleBuildError("应用程序构建", "未知异常");
        return false;
    }
}

std::shared_ptr<infrastructure::ServiceContainer> AppBuilder::getContainer() const
{
    return m_container;
}

void AppBuilder::configureServices()
{

    if (!m_container) {
        throw std::runtime_error("Service container is null");
    }

    // 创建并配置各层注册器
    // 基础设施层注册器
    auto infrastructureRegistrar = std::make_shared<bootstrap::registrars::InfrastructureRegistrar>(m_container);
    infrastructureRegistrar->registerServices();

    // 应用层注册器
    auto applicationRegistrar = std::make_shared<bootstrap::registrars::ApplicationRegistrar>(m_container);
    applicationRegistrar->registerServices();

}

void AppBuilder::initializeServices()
{

    // 初始化已注册的服务
    // 基础设施服务先初始化
    auto infrastructureRegistrar = std::make_shared<bootstrap::registrars::InfrastructureRegistrar>(m_container);
    infrastructureRegistrar->initializeServices();

    // 然后初始化应用层服务
    auto applicationRegistrar = std::make_shared<bootstrap::registrars::ApplicationRegistrar>(m_container);
    applicationRegistrar->initializeServices();

}

bool AppBuilder::createPresentation()
{

    // 创建模块管理器
    m_moduleManager = std::make_unique<ModuleManager>();

    // 注入服务容器
    m_moduleManager->setServiceContainer(m_container);

    // 让ModuleManager负责创建和初始化整个QML应用
    if (!m_moduleManager->createAndInitialize()) {
        qCritical() << "[AppBuilder] Failed to create presentation layer";
        return false;
    }

    return true;
}

void AppBuilder::handleBuildError(const QString& operation, const QString& error)
{
    QString errorMsg = QString("[AppBuilder] %1失败: %2").arg(operation, error);

    // TODO: 使用服务容器中的日志记录器
    // if (m_container && m_container->isRegistered<ILogger>()) {
    //     auto logger = m_container->resolve<ILogger>();
    //     if (logger) {
    //         logger->error(errorMsg);
    //         return;
    //     }
    // }

    // 回退到qDebug
    qCritical() << errorMsg;
}